#include "EyerWASMIndexedDB_GetEvent.hpp"

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <emscripten.h>

extern "C"
{
    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_GetEvent_Get(
            void * ctx,
            int indexedDBKey,
            const char * key
    );

    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_GetEvent_Get_OnSucc(
            void * ctx,
            uint8_t * buf,
            int bufSize,
            const char * contentLengthStr, 
            const char * rangeLengthStr
    )
    {
        int64_t contentLength = atoll(contentLengthStr);
        int64_t rangeLength = atoll(rangeLengthStr);
        Eyer::EyerWASMIndexedDB_GetEvent * event = (Eyer::EyerWASMIndexedDB_GetEvent *)ctx;
        return event->EyerWASMIndexedDB_GetEvent_Get_OnSucc(
                buf,
                bufSize,
                contentLength,
                rangeLength
                );
    }

    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_GetEvent_Get_OnSucc_No_Found(void * ctx)
    {
        Eyer::EyerWASMIndexedDB_GetEvent * event = (Eyer::EyerWASMIndexedDB_GetEvent *)ctx;
        return event->EyerWASMIndexedDB_GetEvent_Get_OnSucc_No_Found();
    }

    EMSCRIPTEN_KEEPALIVE int EyerWASMIndexedDB_GetEvent_Get_OnFail(void * ctx)
    {
        Eyer::EyerWASMIndexedDB_GetEvent * event = (Eyer::EyerWASMIndexedDB_GetEvent *)ctx;
        return event->EyerWASMIndexedDB_GetEvent_Get_OnFail();
    }
}

namespace Eyer
{
    EyerWASMIndexedDB_GetEvent::EyerWASMIndexedDB_GetEvent(
            int indexedDBKey,
            const std::string & key
    )
    {
        m_indexedDBKey = indexedDBKey;
        m_key = key;
    }

    EyerWASMIndexedDB_GetEvent::~EyerWASMIndexedDB_GetEvent()
    {

    }

    int EyerWASMIndexedDB_GetEvent::Run()
    {
        std::unique_lock<std::mutex> lck(mtx);
        EyerWASMIndexedDB_GetEvent_Get(this, m_indexedDBKey, m_key.c_str());
        return 0;
    }

    int EyerWASMIndexedDB_GetEvent::EyerWASMIndexedDB_GetEvent_Get_OnSucc(
            uint8_t * buf,
            int bufSize,
            int64_t contentLength,
            int64_t rangeLength)
    {
        std::unique_lock<std::mutex> lck(mtx);
        m_buffer.SetBuffer(buf, bufSize);
        m_contentLength = contentLength;
        m_rangeLength = rangeLength;
        isSucced = true;
        isFinished = true;
        m_isFound = true;
        cond.notify_all();
        return 0;
    }

    int EyerWASMIndexedDB_GetEvent::EyerWASMIndexedDB_GetEvent_Get_OnSucc_No_Found()
    {
        std::unique_lock<std::mutex> lck(mtx);
        isSucced = true;
        isFinished = true;
        m_isFound = false;
        cond.notify_all();
        return 0;
    }

    int EyerWASMIndexedDB_GetEvent::EyerWASMIndexedDB_GetEvent_Get_OnFail()
    {
        std::unique_lock<std::mutex> lck(mtx);
        isSucced = false;
        isFinished = true;
        m_isFound = false;
        cond.notify_all();
        return 0;
    }

    EyerWASMBuffer EyerWASMIndexedDB_GetEvent::GetBuffer()
    {
        return m_buffer;
    }

    int64_t EyerWASMIndexedDB_GetEvent::GetContentLength()
    {
        return m_contentLength;
    }

    int64_t EyerWASMIndexedDB_GetEvent::GetRangeLength()
    {
        return m_rangeLength;
    }

    bool EyerWASMIndexedDB_GetEvent::IsFound()
    {
        return m_isFound;
    }
}